import json

from django import http
from django.core.paginator import Paginator
from django.db import transaction
from django.shortcuts import render
from django_redis import get_redis_connection
from decimal import Decimal
from orders.models import OrderInfo, OrderGoods
from goods.models import SKU
from meiduo_mall.utils.login import MyloginRequiredMiXinView
from django.utils import timezone
# Create your views here.
from django.views import View

from meiduo_mall.utils.response_code import RET
from users.models import Address


class OrderSettlementView(MyloginRequiredMiXinView):
    def get(self, request):
        try:
            addresses = request.user.addresses.filter(is_deleted=False).all()
        except Exception as e:
            addresses = None
        user = request.user
        redis_conn = get_redis_connection("cart")
        redis_cart = redis_conn.hgetall("cart_%s" % user.id)
        cart_selected = redis_conn.smembers('cart_selected_%s' % user.id)
        total_count = 0
        total_amount = Decimal(0.00)


        sku_list = []
        for sku_id in cart_selected:
            sku = SKU.objects.get(id=sku_id)
            print("1")
            print(redis_cart[sku_id])
            print("2")
            print(int(redis_cart[sku_id]))

            sku_dict = {
                "id": sku.id,
                "name": sku.name,
                "default_image_url": sku.default_image_url.url,
                "price": sku.price,
                "count": int(redis_cart[sku_id]),
                "amount": sku.price * int(redis_cart[sku_id])
            }
            sku_list.append(sku_dict)
            total_count += int(redis_cart[sku_id])
            total_amount += sku.price * int(redis_cart[sku_id])

        freight = Decimal(10.00)
        payment_amount = total_amount + freight

        context = {
            "addresses": addresses,
            "skus": sku_list,
            "freight": freight,
            "total_count": total_count,
            "total_amount": total_amount,
            "payment_amount": payment_amount

        }

        return render(request, 'place_order.html', context=context)


class OrderCommitView(MyloginRequiredMiXinView):
    @transaction.atomic
    def post(self, request):
        dict_data = json.loads(request.body.decode())
        address_id = dict_data.get("address_id")
        pay_method = dict_data.get("pay_method")
        user = request.user


        if not all([address_id, pay_method]):
            return http.HttpResponseForbidden("参数不全")

        try:
            address = Address.objects.get(id=address_id)
        except Exception as e:
            return http.HttpResponseForbidden('地址不存在')

        pay_method = int(pay_method)
        if pay_method not in [OrderInfo.PAY_METHODS_ENUM["CASH"], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
            return http.HttpResponseForbidden("选择的支付方式有误")


        order_id = timezone.now().strftime('%Y%m%d%H%M%S') + "%06d"%user.id

        if pay_method == OrderInfo.PAY_METHODS_ENUM["CASH"]:
            status = OrderInfo.ORDER_STATUS_ENUM["UNSEND"]

        else:
            status = OrderInfo.ORDER_STATUS_ENUM["UNPAID"]

        # TODO 设置保存点
        sid = transaction.savepoint()

        order = OrderInfo.objects.create(
            order_id=order_id, user=user, address=address, total_count=0,
            total_amount=Decimal(0.0), freight=Decimal(10.0),
            pay_method=pay_method, status=status

        )

        redis_conn = get_redis_connection('cart')
        cart_dict = redis_conn.hgetall("cart_%s" % user.id)
        cart_selected_list = redis_conn.smembers("cart_selected_%s" % user.id)

        for sku_id in cart_selected_list:
            while True:
                sku = SKU.objects.get(id=sku_id)
                count = int(cart_dict[sku_id])


                if count > sku.stock:
                    transaction.savepoint_rollback(sid)
                    return http.HttpResponseForbidden("库存数量不足")

                # sku.stock -= count
                # sku.sales += count
                # sku.save()
                old_stock = sku.stock
                old_sales = sku.sales

                new_stock = old_stock - count
                new_sales = old_sales + count

                ret = SKU.objects.filter(id=sku_id, stock=old_stock).update(stock=new_stock, sales=new_sales)

                if ret == 0:
                    # transaction.savepoint_rollback(sid)
                    # return http.HttpResponseForbidden("系统繁忙，提交失败")
                    continue

                order.total_count += count
                order.total_amount += (count * sku.price)


                OrderGoods.objects.create(
                    order=order,
                    sku=sku,
                    count=count,
                    price=sku.price
                )
                break


        order.save()
        transaction.savepoint_commit(sid)

        redis_conn.hdel("cart_%s" % user.id, *cart_selected_list)
        redis_conn.srem("cart_selected_%s" % user.id, *cart_selected_list)


        context = {
            'code': RET.OK,
            'order_id': order_id,
            'payment_amount': order.total_amount + order.freight,
            "pay_method": pay_method

        }


        return http.JsonResponse(context)


class OrderSuccessView(MyloginRequiredMiXinView):
    def get(self, request):
        # 获取参数
        order_id = request.GET.get("order_id")
        payment_amount = request.GET.get("payment_amount")
        pay_method = request.GET.get('pay_method')

        context = {
            "order_id": order_id,
            "payment_amount": payment_amount,
            "pay_method": pay_method,
        }


        return render(request, "order_success.html", context=context)


class UserOrderInfoView(MyloginRequiredMiXinView):
    def get(self, request, page_num):
        # 查询用户订单
        orders = request.user.orders.order_by("-create_time")


        for order in orders:
            order.paymethod_name = OrderInfo.PAY_METHOD_CHOICES[order.pay_method - 1][1]
            order.status_name = OrderInfo.ORDER_STATUS_CHOICES[order.status - 1][1]

            print(order.status)
            print(order.status_name)


        paginate = Paginator(object_list=orders,per_page=3)
        page = paginate.page(page_num)
        orders_list = page.object_list
        current_page = page.number
        total_page = paginate.num_pages


        #2,携带数据渲染
        context = {
            "orders": orders_list,
            "current_page": current_page,
            "total_page": total_page
        }
        return render(request,'user_center_order.html',context=context)


class UserOrderCommentView(MyloginRequiredMiXinView):
    def get(self, request):
        order_id = request.GET.get("order_id")

        try:
            OrderInfo.objects.get(order_id=order_id)
        except OrderInfo.DoesNotExist:
            return http.HttpResponseNotFound('订单不存在')



        try:
            goods = OrderGoods.objects.filter(order_id=order_id, is_commented=False)
        except Exception:
            return http.HttpResponseServerError('订单无未评价商品')

        skus = []
        for good in goods:
            good_dict = {
                "default_image_url": good.sku.default_image_url.url,
                "name": good.sku.name,
                "price": str(good.price),
                "order_id": good.order_id,
                "display_score": good.score,
                "sku_id": good.sku.id

            }
            skus.append(good_dict)

        context = {'skus': skus }

        return render(request, 'goods_judge.html', context)

    def post(self, request):

        json_dict = json.loads(request.body.decode())
        order_id = json_dict.get("order_id")
        sku_id = json_dict.get("sku_id")
        comment = json_dict.get("comment")
        score = json_dict.get("score")
        is_anonymous = json_dict.get("is_anonymous")


        if not all([order_id, sku_id, comment, score]):
            return http.JsonResponse({"code": "4101"})

        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return http.JsonResponse({"code": "4101"})

        try:
            order = OrderGoods.objects.filter(order_id=order_id)
        except Exception as e:
            return http.JsonResponse({"code": "4101"})

        OrderGoods.objects.filter(sku_id=sku_id, order_id=order_id).update(comment=comment,
                                                                           is_anonymous=is_anonymous,
                                                                           is_commented=True, score=score)

        sku.comments += 1
        sku.spu.comments += 1
        sku.save()
        sku.spu.save()

        if OrderGoods.objects.filter(order_id=order_id, is_commented=False).count() == 0:
            OrderInfo.objects.filter(order_id=order_id).update(status=OrderInfo.ORDER_STATUS_ENUM['FINISHED'])

        return http.JsonResponse({'code': RET.OK, 'errmsg': '评价成功'})



